package cloud.consumer.order.controller;



import com.xfanonymous.cloud.entities.Pay;
import com.xfanonymous.cloud.entities.PayDTO;
import com.xfanonymous.cloud.resp.ResultData;
import jakarta.annotation.Resource;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @auther xfanonymous
 * @create 2023-12-22 22:33
 *
 * 客户下单服务请求请求支付8001服务
 * 1. 先写死URL
 *
 * RestTemplate
 * 1. 参数url表示REST请求地址, request表示请求参数, responseType表示返回的对象类型
 * 2. RestTemplate方法
 * <T> T getForObject(String url, Class<T> responseType, Object... uriVariables);
 * <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables);
 * void delete(String url, Object... uriVariables)
 * void put(String url, @Nullable Object request, Object... uriVariables)
 *
 * 问题：
 * 1. 调用的目标API地址和端口号硬编码
 * 2. 调用的目标服务可能存在多个微服务，无法实现负载均衡
 *
 * 解决：需要引入服务治理功能，实现微服务之间的动态注册与发现
 *
 * Consul微服务注册
 * 1. 微服务间调用时，避免硬编码，直接调用服务注册中心上的微服务名称
 */
@RestController
public class OrderController
{
    // 问题：调用其他微服务时写死，硬编码
//    public static final String PaymentSrv_URL = "http://localhost:8001";

    // 使用Consul后，可以通过服务注册中心上的微服务名称调用API
    public static final String PaymentSrv_URL = "http://cloud-payment-service";

    @Resource
    private RestTemplate restTemplate;

    /**
     * 一般情况下，通过浏览器的地址栏输入url，发送的只能是get请求
     * 可以模拟消费者发送get请求，但代码调用post方法，参数PayDTO可以不添加@RequestBody
     */
    @PostMapping(value = "/consumer/pay/add")
    public ResultData addOrder(@RequestBody Pay pay) {
        return restTemplate.postForObject(PaymentSrv_URL + "/pay/add", pay, ResultData.class);
    }

    @DeleteMapping(value = "/consumer/pay/del/{id}")
    public ResultData deleteOrder(@PathVariable("id") Integer id) {
        System.out.println("id = " + id);
        // 方法返回结果为空
        restTemplate.delete(PaymentSrv_URL + "/pay/del/"+id, id);
        return ResultData.success(id);
    }

    @PutMapping(value = "/consumer/pay/update")
    public ResultData updateOrder(@RequestBody PayDTO payDTO) {
        restTemplate.put(PaymentSrv_URL + "/pay/update", payDTO);
        return restTemplate.getForObject(PaymentSrv_URL + "/pay/get/"+payDTO.getId(), ResultData.class, payDTO.getId());
    }

    @GetMapping(value = "/consumer/pay/get/{id}")
    public ResultData getOrder(@PathVariable("id") Integer id)
    {
        return restTemplate.getForObject(PaymentSrv_URL + "/pay/get/"+id, ResultData.class, id);
    }

    @GetMapping(value = "/consumer/pay/getall")
    public ResultData getAll()
    {
        return restTemplate.getForObject(PaymentSrv_URL + "/pay/getall", ResultData.class);
    }


    // TODO：LB，通过restTemplate做客户端LB，调用Consul中注册的微服务
    @GetMapping(value = "/consumer/pay/get/info")
    private String getInfoByConsul()
    {
        return restTemplate.getForObject(PaymentSrv_URL + "/pay/get/info", String.class);
    }


    // TODO：获取Consul中注册的微服务列表
    @Resource
    private DiscoveryClient discoveryClient;

    @GetMapping("/consumer/discovery")
    public String discovery() {

        List<String> services = discoveryClient.getServices();
        for (String element : services) {
            System.out.println(element);
        }

        System.out.println("===================================");

        List<ServiceInstance> instances = discoveryClient.getInstances("cloud-payment-service");
        for (ServiceInstance element : instances) {
            System.out.println(element.getServiceId()+"\t"+
                    element.getHost()+"\t"+
                    element.getPort()+"\t"+
                    element.getUri());
        }

        return instances.get(0).getServiceId()+":"+instances.get(0).getPort();
    }
    /**
     * cloud-consumer-order
     * cloud-payment-service
     * consul
     * ===================================
     * cloud-payment-service	localhost	8001	http://localhost:8001
     * cloud-payment-service	localhost	8002	http://localhost:8002
     * cloud-payment-service	localhost	8003	http://localhost:8003
     */

}
